/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.dtgenerator.core.mgrImpl.mgrMethods;

import com.inspur.edp.bef.bizentity.operation.BizMgrAction;
import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.bef.component.base.VoidReturnType;
import com.inspur.edp.bef.component.detailcmpentity.bemgr.BEMgrComponent;
import com.inspur.edp.bef.component.detailcmpentity.bemgr.BEMgrMethod;
import com.inspur.edp.bef.component.detailcmpentity.bemgr.BEMgrMethodParameter;
import com.inspur.edp.bef.dtgenerator.common.IMetadataPool;
import com.inspur.edp.bef.dtgenerator.common.Utils;
import com.inspur.edp.bef.dtgenerator.core.BefCoreGenCtx;
import com.inspur.edp.caf.generator.baseInfo.ParameterInfo;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.utils.ExpressionUtils;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

//
//     * var factory = BEManagerContext.MgrActionAssemblerFactory as IEv1MgrMgrActionAssembler;
//     * if(factory != null)
//     * {
//     *     var ass = factory.GetxxxAssembler();
//     *     if(ass != null)
//     *     {
//     *         ass.DemandFuncPermission();
//     *     }
//     * }
//
public class MgrImplMethodGenerator extends ClassMethodGenerator {
  private BizMgrAction action;
  private BefCoreGenCtx coreGenCtx;
  // private Type interfaceType;
  private IMetadataPool pool;
  private BEMgrComponent compMetadata;
  private BEMgrMethod method;
  private java.util.ArrayList<ParameterInfo> parList;

  public MgrImplMethodGenerator(BizMgrAction action, BefCoreGenCtx coreGenCtx, IMetadataPool pool) {
    this.action = action;
    this.coreGenCtx = coreGenCtx;
    // this.interfaceType = interfaceType;
    this.pool = pool;
  }

  @Override
  protected Block buildMethodBody() {
    Block block = ast.newBlock();
    buildAuthorityStatement(block);

    VariableDeclarationFragment actionDeclarationFragment = ast.newVariableDeclarationFragment();
    actionDeclarationFragment.setName(ast.newSimpleName("action"));
    ClassInstanceCreation creation = ast.newClassInstanceCreation();
    creation.setType(ast.newSimpleType(ast.newName(method.getClassName())));
    MethodInvocation getMgrContextInvocation = ast.newMethodInvocation();
    getMgrContextInvocation.setName(ast.newSimpleName("getBEManagerContext"));
    creation.arguments().add(getMgrContextInvocation);
    for (ParameterInfo par : preparePars()) {
      creation.arguments().add(ast.newSimpleName(Utils.getParameterName(par)));
    }

    actionDeclarationFragment.setInitializer(creation);
    VariableDeclarationStatement actionDeclaration =
        ast.newVariableDeclarationStatement(actionDeclarationFragment);
    actionDeclaration.setType(ast.newSimpleType(ast.newName(method.getClassName())));
    block.statements().add(actionDeclaration);

    MethodInvocation executeInvocation = ast.newMethodInvocation();
    executeInvocation.setName(ast.newSimpleName("Execute"));
    executeInvocation.arguments().add(ast.newSimpleName("action"));
    block.statements().add(ast.newExpressionStatement(executeInvocation));

    if (method.getReturnValue() instanceof VoidReturnType) {

    } else {
      ReturnStatement returnStatement = ast.newReturnStatement();
      MethodInvocation methodInvocation=ast.newMethodInvocation();
      methodInvocation.setName(ast.newSimpleName("getResult"));
      methodInvocation.setExpression(ast.newSimpleName("action"));
      returnStatement.setExpression(methodInvocation);
      block.statements().add(returnStatement);
    }
    return block;
  }

  private void buildAuthorityStatement(Block block) {
//    getBEManagerContext().checkAuthority("BeTest");
    MethodInvocation beContextInvocation = ast.newMethodInvocation();
    beContextInvocation.setName(ast.newSimpleName("getBEManagerContext"));
    MethodInvocation checkInvocation = ExpressionUtils.getMethodInvocation(ast, beContextInvocation, "checkAuthority");
    checkInvocation.arguments().add(ExpressionUtils.getStringLiteral(ast, action.getCode()));

    block.statements().add(ast.newExpressionStatement(checkInvocation));
  }

  @Override
  protected void doInitialize() {
    GspMetadata metadata = pool.getMetadata(action.getComponentPkgName(), action.getComponentId());
    GspComponent comp = (GspComponent) metadata.getContent();
    if (!comp.getComponentType().equals("BEMgrComponent")) {
      throw new RuntimeException("错误的类型");
    }
    compMetadata = (BEMgrComponent) comp;
    method = (BEMgrMethod) comp.getMethod();
    // compMetadata =
    // (BEMgrComponent)pool.getMetadataContent<GspComponentMetadata>(action.getComponentPkgName(),
    // action.getComponentId()).Content;
    // method = compMetadata.BEMgrMethod;
  }

  @Override
  protected java.util.ArrayList<ModifierKeyword> getAccessModifiers() {
    return new java.util.ArrayList<ModifierKeyword>(
        java.util.Arrays.asList(ModifierKeyword.PUBLIC_KEYWORD));
  }

  @Override
  protected String getMethodName() {
    return action.getCode();
  }

  @Override
  protected java.util.ArrayList<ParameterInfo> getParameterCollection() {
    return preparePars();
  }

  private java.util.ArrayList<ParameterInfo> preparePars() {
    java.util.ArrayList<ParameterInfo> result = new java.util.ArrayList<ParameterInfo>();
    if (method.getParameterCollection() != null) {
      for (Object item : method.getParameterCollection()) {
        BEMgrMethodParameter par = (BEMgrMethodParameter) item;
        result.add(com.inspur.edp.cef.generator.overall.Utils.buildParGenInfo(par, coreGenCtx, null));
      }
    }
    return result;
  }

  @Override
  protected TypeInfo getReturnType() {
    return com.inspur.edp.cef.generator.overall.Utils.getReturnType(method, coreGenCtx.getBeGenCtx());
  }
}
